package top.chukongxiang.monitorservice.config;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.chukongxiang.monitorservice.config.conditation.os.ConditionalOnOS;
import top.chukongxiang.monitorservice.config.conditation.os.Os;
import top.chukongxiang.monitorservice.jna.HCNetSDK;
import top.chukongxiang.monitorservice.jna.PlayCtrl;
import top.chukongxiang.monitorservice.model.constant.ConfigKeyConstant;
import top.chukongxiang.monitorservice.tools.H2Util;

/**
 * @author 楚孔响
 * @version 1.0
 * @date 2023/10/18 16:11
 */
@Slf4j
@Configuration
public class JnaConfiguration {

    private static String sdkFolder;

    public JnaConfiguration() {
        updateSdkFolder();
    }

    public void updateSdkFolder() {
        sdkFolder = H2Util.getConfigValue(ConfigKeyConstant.HK_SDK_FOLDER);
        if (StrUtil.isBlank(sdkFolder)) {
            throw new RuntimeException("海康SDK文件夹为空");
        }
    }

    @Bean
    @ConditionalOnOS({Os.Windows, Os.Linux})
    public HCNetSDK hcNetSdk() {
        OsInfo osInfo = SystemUtil.getOsInfo();
        HCNetSDK hcNetSdk;
        if (osInfo.isWindows()) {
            hcNetSdk = Native.load(FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "HCNetSDK.dll")), HCNetSDK.class);
        } else if (osInfo.isLinux()) {
            hcNetSdk = Native.load(FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "libhcnetsdk.so")), HCNetSDK.class);
            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
            //这里是库的绝对路径，请根据实际情况修改，注意改路径必须有访问权限
            String strPath1 = FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "libcrypto.so.1.1"));
            String strPath2 = FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "libssl.so.1.1"));

            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
            ptrByteArray1.write();
            hcNetSdk.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());

            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
            ptrByteArray2.write();
            hcNetSdk.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());

            String strPathCom = FileUtil.getAbsolutePath(sdkFolder);
            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
            struComPath.write();
            hcNetSdk.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
        } else {
            log.error("不支持的操作系统:{}", osInfo.getName());
            throw new RuntimeException("不支持的操作系统:" + osInfo.getName());
        }
        return hcNetSdk;
    }

    @Bean
    @ConditionalOnOS({Os.Windows, Os.Linux})
    public PlayCtrl playCtrl() {
        OsInfo osInfo = SystemUtil.getOsInfo();
        if (osInfo.isWindows()) {
            return Native.load(FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "PlayCtrl.dll")), PlayCtrl.class);
        } else if (osInfo.isLinux()) {
            return Native.load(FileUtil.getAbsolutePath(FileUtil.file(sdkFolder, "libPlayCtrl.so")), PlayCtrl.class);
        }  else {
            log.error("不支持的操作系统:{}", osInfo.getName());
            throw new RuntimeException("不支持的操作系统:" + osInfo.getName());
        }
    }

}
